#include "Engine/StdAfx.h"
#include <Engine/Foundation/Mouse.h>
#include <Engine/GlobalEnv.h>
#include <Engine/IEngine.h>
#include <Engine/ITimer.h>

namespace fastbird
{
	void Mouse::GetCurrentMousePos(long& x, long& y)
	{
#ifdef _FBENGINE_FOR_WINDOWS_
		POINT cursor;
		GetCursorPos(&cursor);
		ScreenToClient(gEnv->pEngine->GetWindowHandle(), &cursor);
		x = cursor.x;
		y = cursor.y;
#else
		assert(0);
#endif _FBENGINE_FOR_WINDOWS_
	}

	Mouse::Mouse()
	{		
		mButtonsDown = 0;
		mButtonClicked = 0;
		mButtonDoubleClicked = 0;
		mDeltaX = 0;
		mDeltaY = 0;
		GetCurrentMousePos(mAbsX, mAbsY);
		mValid = true;
	}

	void Mouse::PushEvent(const MouseEvent& mouseEvent)
	{
		/*IEngine::Log("usFlags = %x, usButtonFlags = %x, usButtonData = %x, ulRawButtons = %x, lLastX = %d, lLastY = %d, ulExtraInformation = %d",
						mouseEvent.usFlags,
						mouseEvent.usButtonFlags,
						mouseEvent.usButtonData,
						mouseEvent.ulRawButtons,
						mouseEvent.lLastX,
						mouseEvent.lLastY,
						mouseEvent.ulExtraInformation);*/

		mDeltaX += mouseEvent.lLastX;
		mDeltaY += mouseEvent.lLastY;
		mAbsX += mouseEvent.lLastX;
		mAbsY += mouseEvent.lLastY;

		if (mouseEvent.usButtonFlags & MOUSE_BUTTON_FLAG_LEFT_BUTTON_DOWN)
		{
			mButtonsDown |= MOUSE_BUTTON_LEFT;
		}
		if (mouseEvent.usButtonFlags & MOUSE_BUTTON_FLAG_RIGHT_BUTTON_DOWN)
		{
			mButtonsDown |= MOUSE_BUTTON_RIGHT;
		}
		if (mouseEvent.usButtonFlags & MOUSE_BUTTON_FLAG_MIDDLE_BUTTON_DOWN)
		{
			mButtonsDown |= MOUSE_BUTTON_MIDDLE;
		}
		if (mouseEvent.usButtonFlags & MOUSE_BUTTON_FLAG_BUTTON_4_DOWN)
		{
			mButtonsDown |= MOUSE_BUTTON_4;
		}
		if (mouseEvent.usButtonFlags & MOUSE_BUTTON_FLAG_BUTTON_5_DOWN)
		{
			mButtonsDown |= MOUSE_BUTTON_5;
		}

		if (mouseEvent.usButtonFlags & MOUSE_BUTTON_FLAG_LEFT_BUTTON_UP)
		{
			mButtonsDown &= ~MOUSE_BUTTON_LEFT;
			mButtonClicked |= MOUSE_BUTTON_LEFT;
		}
		if (mouseEvent.usButtonFlags & MOUSE_BUTTON_FLAG_RIGHT_BUTTON_UP)
		{
			mButtonsDown &= ~MOUSE_BUTTON_RIGHT;
			mButtonClicked |= MOUSE_BUTTON_RIGHT;
		}
		if (mouseEvent.usButtonFlags & MOUSE_BUTTON_FLAG_MIDDLE_BUTTON_UP)
		{
			mButtonsDown &= ~MOUSE_BUTTON_MIDDLE;
			mButtonClicked |= MOUSE_BUTTON_MIDDLE;
		}
		if (mouseEvent.usButtonFlags & MOUSE_BUTTON_FLAG_BUTTON_4_UP)
		{
			mButtonsDown &= ~MOUSE_BUTTON_4;
			mButtonClicked |= MOUSE_BUTTON_4;
		}
		if (mouseEvent.usButtonFlags & MOUSE_BUTTON_FLAG_BUTTON_5_UP)
		{
			mButtonsDown &= ~MOUSE_BUTTON_5;
			mButtonClicked |= MOUSE_BUTTON_5;
		}

		if (mouseEvent.usButtonFlags & MOUSE_BUTTON_FLAG_MOUSE_WHEEL)
		{
			mWheel.push((long)mouseEvent.usButtonData);
		}
	}

	void Mouse::EndFrame()
	{
		mDeltaX = 0;
		mDeltaY = 0;
		mButtonClicked = 0;
		while(!mWheel.empty())
			mWheel.pop();
		mValid = true;
	}

	bool Mouse::IsValid() const
	{
		return mValid && (mDeltaX != 0 || mDeltaY != 0 || !mWheel.empty() || mButtonClicked != 0 || mButtonsDown != 0) ;
	}

	void Mouse::Invalid()
	{
		mValid = false;
	}

	void Mouse::GetDeltaXY(long &x, long &y) const
	{
		x = mDeltaX;
		y = mDeltaY;
	}
}